package com.tiancheng.trade.merchant.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.nio.charset.StandardCharsets;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.time.Instant;
import java.util.Base64;

/**
 * 银联商务工具类
 */
public final class UmsUtil {
    private static final char[] charArray = "1234567890qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM".toCharArray();

    private static final char[] HEXCHAR = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f'};

    public static final String KEY_ALGORITHM = "DESede";
    public static final String KEY_ALGORITHM_PADDING = "DESede/ECB/PKCS5Padding";
    public static final String ENCODE = "UTF-8";

    /**
     * 对称加密DESede
     */
    public static final String DES_ALGORITHM = "DESede";

    /**
     * sha-256签名
     *
     * @param str {@link String} 明文数据
     * @return {@link String} 签名后转化为十六进制返回
     */
    public static String sign(String str) throws NoSuchAlgorithmException, UnsupportedEncodingException {
        MessageDigest messageDigest;
        messageDigest = MessageDigest.getInstance(KEY_ALGORITHM);
        messageDigest.update(str.getBytes(ENCODE));
        return toHexString(messageDigest.digest());
    }

    /**
     * des加密
     *
     * @param data {@link String}
     * @param key  {@link String}
     * @return {@link String}
     */
    public static String encrypt(String data, String key) throws Exception {

        byte[] keyByte = key.getBytes();
        SecretKey sk = new SecretKeySpec(keyByte, DES_ALGORITHM);
        Cipher cipher = Cipher.getInstance(DES_ALGORITHM);
        cipher.init(Cipher.ENCRYPT_MODE, sk);
        return toHexString(cipher.doFinal(data.getBytes(ENCODE)));
    }

    /**
     * des解密
     *
     * @param encryptData {@link String} 加密数据
     * @param key  {@link String}
     * @return {@link String}
     */
    public static String decrypt(String encryptData, String key) throws Exception {

        byte[] keyByte = key.getBytes();
        SecretKey sk = new SecretKeySpec(keyByte, KEY_ALGORITHM);
        Cipher cipher = Cipher.getInstance(KEY_ALGORITHM_PADDING);
        cipher.init(Cipher.DECRYPT_MODE, sk);
        return new String(cipher.doFinal(CommonUtil.toBytes(encryptData)), ENCODE);
    }


    /**
     * byte数组转化为十六进制
     *
     * @param b byte[]
     * @return {@link String}
     */
    public static String toHexString(byte[] b) {
        StringBuilder sb = new StringBuilder(b.length * 2);
        for (byte value : b) {
            sb.append(HEXCHAR[(value & 0xf0) >>> 4]);
            sb.append(HEXCHAR[value & 0x0f]);
        }
        return sb.toString();
    }

    /**
     * 流水号生成器，21位，组成：4位随机因子_当前时间毫秒数，例：l5d0_0001604979731025
     *
     * @return {@link String}
     */
    public static String requestSeqHelper() {
        return getRandomCharSequence(4) + "_" + String.format("%015d", Instant.now().toEpochMilli());
    }

    /**
     * acct生成器，32位，组成：ty_outside_4位随机因子_当前时间毫秒数，例：ty_outside_l5d0_0001604979731025
     *
     * @return {@link String}
     */
    public static String acctHelper() {
        return "ty_outside_" + getRandomCharSequence(4) + "_" + String.format("%015d", Instant.now().toEpochMilli());
    }

    /**
     * 获取指定长度随机字符串，可包含数字、大小写字母
     *
     * @param length int 长度
     * @return {@link String}
     */
    public static String getRandomCharSequence(int length) {
        StringBuilder str = new StringBuilder();
        for (int i = 0; i < length; i++) {
            str.append(charArray[(int) (Math.random() * charArray.length)]);
        }
        return str.toString();
    }

}
